﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using Core;

namespace Core
{
    public struct GetMainCamera : IEventData
    {
        public Camera mainCamera;
    }

    public struct GetUICamera : IEventData
    {
        public Camera uiCamera;
    }

    public class CameraSystem : EntitySystem, IAwake
    {
        private Camera mainCamera;
        private Camera uiCamera;
        private UniversalAdditionalCameraData mainUrpData;

        public void Awake()
        {
            Subscribe<GetMainCamera>(OnGetMainCamera);
            Subscribe<GetUICamera>(OnGetUICamera);
            CreateCamera();
        }

        private void CreateCamera()
        {
            var config = new GetCoreData().Publish().coreData;

            var initMono = new GetInitMono().Publish().mono;
            if (initMono == null)
            {
                Debug.LogError("game mono is null");
                return;
            }

            var gameTran = initMono.transform;

            // 主相机
            GameObject mainGO = new GameObject("MainCamera");
            mainGO.transform.SetParent(gameTran);
            mainGO.transform.localPosition = Vector3.zero;
            mainGO.AddComponent<AudioListener>();
            mainCamera = mainGO.AddComponent<Camera>();
            mainUrpData = mainCamera.GetUniversalAdditionalCameraData();
            mainUrpData.renderType = CameraRenderType.Base;
            mainCamera.cullingMask = ~(1 << config.uiMask);
            mainCamera.orthographic = false;

            // UI相机
            GameObject uiGO = new GameObject("UICamera");
            uiGO.transform.SetParent(gameTran);
            uiGO.transform.localPosition = config.uiCameraPos;
            uiCamera = uiGO.AddComponent<Camera>();
            var uiUrpData = uiCamera.GetUniversalAdditionalCameraData();
            uiUrpData.renderType = CameraRenderType.Overlay;
            uiUrpData.renderShadows = false;
            uiCamera.cullingMask = 1 << config.uiMask;
            uiCamera.orthographic = true;
            uiCamera.orthographicSize = config.referenceResolution.y / 2;
            uiCamera.farClipPlane = Mathf.Abs(config.cameraFar * 2);
            if (config.uiCameraRendererIndex > 0)
                uiUrpData.SetRenderer(config.uiCameraRendererIndex);

            PushCamera(uiCamera);
        }

        private void PushCamera(Camera camera)
        {
            mainUrpData.cameraStack.Add(camera);
        }

        private void OnGetMainCamera(ref GetMainCamera data)
        {
            data.mainCamera = mainCamera;
        }

        private void OnGetUICamera(ref GetUICamera data)
        {
            data.uiCamera = uiCamera;
        }
    }
}
